package com.splant.android.smart.CommunicationLevel.Bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

import com.splant.android.smart.ProtocolLevel.CRC16;
import com.splant.android.smart.SystemDefinedLevel.Utils.System_DataType_Util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;


/**
 * Created by Administrator on 2015/11/3.
 */
public class BluetoothClientManager {

//    public static final int MESSAGE_WRITE=4;
//    public static final int MESSAGE_READ = 3;
//    public static final int MESSAGE_WRITEFINISH=5;

    private String TAG="Comm";
    private int mState;//蓝牙当前状态
    public static final int STATE_NONE = 0;       // we're doing nothing
    public static final int STATE_CONNECTING = 1; // now initiating an outgoing connection
    public static final int STATE_CONNECTED = 2;  // now connected to a remote device
    public static final int STATE_CONNECTFAILURE=4;

    private ConnectThread mConnectThread;
    private CommThread commThread;

    private BluetoothAdapter bluetoothApt = BluetoothAdapter.getDefaultAdapter();


  //  private final String UUIDStr="00001102-0000-1000-8000-00805F9B34FB";
    private final String UUIDStr="00001101-0000-1000-8000-00805F9B34FB";
    private final int READBUFFER_LENGTH=2048;
    private byte[] readBuffer;

    private static BluetoothClientManager bluetoothClientManager;
    public static  BluetoothClientManager getInstance(IBluetoothComm iBluetoothComm)
    {
        if (bluetoothClientManager==null) {
            synchronized (BluetoothClientManager.class)
            {
                if (bluetoothClientManager==null)
                    bluetoothClientManager=new BluetoothClientManager(iBluetoothComm);
            }
        }
        return bluetoothClientManager;
    }
    public BluetoothClientManager(IBluetoothComm iBluetoothComm)
    {
        this.iBluetoothComm=iBluetoothComm;
        mState=STATE_NONE;
        readBuffer=new byte[READBUFFER_LENGTH];
    }
    public Set<BluetoothDevice> getBondedDevices()
    {
       return bluetoothApt.getBondedDevices();
    }
    private synchronized void setState(int state) {
        mState = state;
    }
    public int getConnectState()
    {
     return mState;
    }
    public boolean getBluetoothConnectState()
    {
        int flag = -1;
        if (bluetoothApt == null){
            return false;     //error
        }
        else if(bluetoothApt.isEnabled())
        {
            int a2dp = bluetoothApt.getProfileConnectionState(BluetoothProfile.A2DP);              //可操控蓝牙设备，如带播放暂停功能的蓝牙耳机
            int headset = bluetoothApt.getProfileConnectionState(BluetoothProfile.HEADSET);        //蓝牙头戴式耳机，支持语音输入输出
            int health = bluetoothApt.getProfileConnectionState(BluetoothProfile.HEALTH);

            int gatt = bluetoothApt.getProfileConnectionState(BluetoothProfile.GATT);
            int gattsvr = bluetoothApt.getProfileConnectionState(BluetoothProfile.GATT_SERVER);
            //蓝牙穿戴式设备

            //查看是否蓝牙是否连接到三种设备的一种，以此来判断是否处于连接状态还是打开并没有连接的状态

            if (a2dp == BluetoothProfile.STATE_CONNECTED) {
                flag = a2dp;
            } else if (headset == BluetoothProfile.STATE_CONNECTED) {
                flag = headset;
            } else if (health == BluetoothProfile.STATE_CONNECTED) {
                flag = health;
            }
            else if (gatt== BluetoothProfile.STATE_CONNECTED)
                flag=gatt;
            else if (gattsvr== BluetoothProfile.STATE_CONNECTED)
                flag=gattsvr;

            //说明连接上了三种设备的一种

        }
        if (flag != -1) {
            return true;
        } else
            return false;
    }

    private BluetoothDevice bluetoothDevice;

    private void setDevice(BluetoothDevice bluetoothDevice)
    {
        this.bluetoothDevice=bluetoothDevice;
    }
    public BluetoothDevice getDevice()
    {
       return this.bluetoothDevice;
    }

    public void openBluetooth()
    {
        if (bluetoothApt!=null&&!bluetoothApt.isEnabled())
            bluetoothApt.enable();
    }
    public void closeBluetooth()
    {
        if (bluetoothApt!=null&&bluetoothApt.isEnabled())
            bluetoothApt.disable();
    }

    public boolean isEnabled()
    {
        return  bluetoothApt.isEnabled();
    }
    public synchronized void connect(BluetoothDevice device) {

            if (mConnectThread != null) {
                mConnectThread.cancel(); mConnectThread = null;
            }
            mConnectThread=new ConnectThread(device);
            mConnectThread.start();
            setDevice(device);
            setState(STATE_CONNECTING);
            iBluetoothComm.returnCommState(STATE_CONNECTING);
    }
    public void writeDatas(byte[] datas)
    {
        CommThread c;
        synchronized (this)
        {
            if (mState!=STATE_CONNECTED)return;
            c=commThread;
        }
        if (c!=null)
            c.writeDatas(datas);
    }
    private class ConnectThread extends Thread {
        private BluetoothSocket mmSocket;
        private BluetoothDevice mmDevice;
        public ConnectThread(BluetoothDevice device) {
            mmDevice = device;
            BluetoothSocket tmp = null;
            try
            {
                tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(UUIDStr));
            }
            catch (IOException e) {
                Log.e("bluetooth_socket", "创建scoket异常！");
            }
            mmSocket = tmp;
        }
        public void run()
        {
            bluetoothApt.cancelDiscovery();
            try
            {
                try
                {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mmSocket.connect();
                Log.e("bluetooth_socket", "连接成功！");
            }
            catch (IOException e)
            {
                setState(STATE_CONNECTFAILURE);
                iBluetoothComm.returnCommState(STATE_CONNECTFAILURE);
                Log.e("bluetooth_socket", "连接异常"+e.toString());
                try
                {
                    mmSocket.close();
                }
                catch (IOException e2)
                {
                    Log.e("bluetooth_socket", "关闭异常"+e.toString());
                }
                return;
            }

            connected(mmSocket);
        }
        public void cancel()
        {
            try
            {
                mmSocket.close();
                mmSocket=null;
            }
            catch (IOException e) {

            }
        }
    }
    public synchronized void connected(BluetoothSocket socket)
    {
        if (commThread != null) {commThread.cancel(); commThread = null;}
        commThread=new CommThread(socket);
        commThread.start();
        setState(STATE_CONNECTED);

        iBluetoothComm.returnCommState(STATE_CONNECTED);//连接成功！
    }
    private class CommThread extends Thread
    {
        private BluetoothSocket mmSocket;
        private InputStream mmInStream ;
        private OutputStream mmOutStream ;
        private boolean flag=true;
        public CommThread(BluetoothSocket mmSocket)
        {
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            this.mmSocket = mmSocket;
            try
            {
                tmpIn=mmSocket.getInputStream();
                tmpOut=mmSocket.getOutputStream();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            mmInStream=tmpIn;
            mmOutStream=tmpOut;
        }
        public void writeDatas(byte[] datas)
        {
            try
            {
                mmOutStream.write(datas);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        private byte[] addCrc(byte[] datas)
        {
            if (datas!=null)
                datas= CRC16.addCrc16Bytes(datas);
            return datas;
        }
        @Override
        public void run()
        {
            while (flag)
            {
                if (mmSocket!=null&&mmSocket.isConnected())
                {
                    try
                    {
                        int bytesNum=mmInStream.read(readBuffer);
                        if (bytesNum>0)
                        {
                            byte[] revcBytes= System_DataType_Util.getPartBytes(readBuffer,bytesNum);


                            crcControlRevc(revcBytes);
                        }


                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        public void cancel() {
            try
            {
                flag=false;
                mmSocket.close();
                mmSocket=null;
            } catch (IOException e) {
                Log.e("bluetooth_socket", "关闭异常1"+e.toString());
            }
        }
    }

    private long preRecvDateTime=0;
    private final static int RECV_MAXINV=100;
    private void crcControlRevc(byte[] revcBytes)
    {
        long curRecvDateTime=System.currentTimeMillis();
        if (totalRecvDatas!=null)
        {
            if (curRecvDateTime-preRecvDateTime>RECV_MAXINV)
            {
                totalRecvDatas=null;
                Log.i("Comm", "接收时间差= "+(curRecvDateTime-preRecvDateTime));
            }

        }
        preRecvDateTime=curRecvDateTime;
        if (totalRecvDatas==null)
            totalRecvDatas=revcBytes;
        else
            totalRecvDatas= System_DataType_Util.mergeBytes(totalRecvDatas,revcBytes);

        if (CRC16.checkCRC(totalRecvDatas))
        {
            Log.i("Comm", "收到内容通过CRC: " + System_DataType_Util.bytesToHexString(totalRecvDatas," "));
            totalRecvDatas= System_DataType_Util.getPartBytes(totalRecvDatas,totalRecvDatas.length-2);
            iBluetoothComm.receiveBytes(totalRecvDatas);
            totalRecvDatas=null;
        }
        else
        Log.i("Comm", "收到内容: " + System_DataType_Util.bytesToHexString(revcBytes," "));
    }
    private void timerControlRevc(byte[] revcBytes)
    {
        if (recvTask==null||recvTask.getRevcState()==false)
        {
            recvTask=new RecvTask();
            totalRecvDatas=revcBytes;
            recvTask.setRevcState(true);
            Timer timer=new Timer();
            timer.schedule(recvTask,0,INTERVAL);
        }
        else
        {
            if (totalRecvDatas!=null)
                totalRecvDatas= System_DataType_Util.mergeBytes(totalRecvDatas,revcBytes);
        }
    }
    public IBluetoothComm iBluetoothComm;
    public interface IBluetoothComm
    {
        void receiveBytes(byte[] bytes);
        void returnCommState(int commState);
    }
    private RecvTask recvTask;
    private final int REVCINTERVAL_MAXTIME=50;
    private byte[] totalRecvDatas;
    private final  int INTERVAL=2;
    private class RecvTask extends TimerTask
    {
        private boolean isRevcState;
        private int recvInterval;
        public boolean getRevcState()
        {
            return isRevcState;
        }
        public void setRevcState(boolean revcState)
        {
            isRevcState=revcState;
        }
        @Override
        public void run()
        {
            if (recvInterval>=REVCINTERVAL_MAXTIME)
            {
                if (totalRecvDatas!=null)
                iBluetoothComm.receiveBytes(totalRecvDatas);
                cancel();
                isRevcState=false;
            }
            else
            {
                recvInterval+=INTERVAL;
            }
        }
    }

    public void destroyBluntoothComm()
    {
        if (commThread != null) {   Log.i("Comm", "通讯释放");   commThread.cancel(); commThread = null;}
        if (recvTask!=null)
            recvTask.cancel();
        bluetoothClientManager=null;
    }
}
